import * as dotenv from 'dotenv';
import { NestFactory } from '@nestjs/core';
import { NestExpressApplication } from '@nestjs/platform-express';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { HttpExceptionFilter } from './shared/filters/http.exception.filter';
import { ValidationPipe } from './shared/pipe/validation.pipe';
import { ResponseInterceptor } from './shared/interceptor/response.interceptor';
import * as serveStatic from 'serve-static';
import { resolve, join } from 'path';
import { Logger } from '@nestjs/common';
import * as helmet from 'helmet';
import * as rateLimit from 'express-rate-limit'
import * as csurf from 'csurf';
import { RedisIoAdapter } from './adapter/redis.io.adapter';
import adminConfig from './config/admin.config';
import * as session from 'express-session';
import { AppModule } from './app.module';
import { WsAdapter } from '@nestjs/platform-ws';

dotenv.config();

const PORT = process.env.PORT || 3000;
const PREFIX = process.env.PREFIX || '/';
declare const module: any;
Logger.log(`当前端口==》${PORT}`);

async function bootstrap() {
  const appOptions = { cors: true, logger: true };//跨域访问
  const app = await NestFactory.create<NestExpressApplication>(
    AppModule,
    appOptions,
  );
  app.setGlobalPrefix(PREFIX);
  const options = new DocumentBuilder()
    .setTitle('nestjs api文档')
    .setDescription('nestjs api接口文档')
    .setBasePath(PREFIX)
    .addBearerAuth({ type: 'apiKey', in: 'header', name: 'Authorization' })
    .setVersion('1.10')
    .setVersion('0.0.1')
    .build();
  const document = SwaggerModule.createDocument(app, options);
  SwaggerModule.setup('/docs', app, document);

  // 访问频率限制
  app.use(
    rateLimit({
      windowMs: 15 * 60 * 1000, // 15分钟
      max: 100, // 限制15分钟内最多只能访问100次
    }),
  );
  //session
  app.use(session({ secret: 'justinzyh', cookie: { maxAge: 60000 } }))
  //配置静态资源目录
  app.useStaticAssets(join(__dirname, '../..', 'public'), {
    prefix: adminConfig.staticPrefixPath,
  });
  // Web漏洞的
  app.use(helmet());
  // 跨站点请求伪造
  // app.use(csurf());
  // 全局注册错误的过滤器(错误异常)
  app.useGlobalFilters(new HttpExceptionFilter());
  // 全局注册拦截器(成功返回格式)
  app.useGlobalInterceptors(new ResponseInterceptor());
  // 全局使用管道(数据校验)
  app.useGlobalPipes(new ValidationPipe());
  app.use('/public', serveStatic(join(__dirname, '../../public'), {
    maxAge: '1d',
    extensions: ['jpg', 'jpeg', 'png', 'gif'],
  }));
  //适配器
  app.useWebSocketAdapter(new RedisIoAdapter(app));

  await app.listen(PORT, () => {
    Logger.log(`服务已经启动,请访问:http://localhost:${PORT}/${PREFIX}`);
  });

  if (module.hot) {
    module.hot.accept();
    module.hot.dispose(() => app.close());
  }
}
bootstrap().catch(e => Logger.error('错误', e));
